﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace MyEmulators2
{
    public class EmulatorProfile: DBInterface
    {
        public EmulatorProfile(Emulator emu, bool isNew)
        {
            if (emu != null)
            {
                this.EmulatorID = emu.UID;

                if (isNew) //used when creating a new profile
                {
                    this.ID = -2;
                    this.Title = "New Profile";
                }
                else //create default profile using emulator settings
                {
                    this.ID = -1;
                    this.Title = "Default";
                }

                this.EmulatorPath = emu.PathToEmulator;
                this.WorkingDirectory = emu.WorkingFolder;
                this.Arguments = emu.Arguments;
                this.UseQuotes = emu.UseQuotes;
                this.SuspendMP = emu.SuspendRendering;

                this.GoodMergePref1 = emu.GoodmergePref1;
                this.GoodMergePref2 = emu.GoodmergePref2;
                this.GoodMergePref3 = emu.GoodmergePref3;

                this.MountImages = emu.MountImages;
                this.EscapeToExit = emu.EscapeToExit;

            }
            else //empty
            {
                this.ID = -2;
                this.Title = "";
                this.EmulatorID = -3;
                this.EmulatorPath = "";
                this.WorkingDirectory = "";
                this.Arguments = "";
                this.UseQuotes = null;
                this.SuspendMP = null;
                this.GoodMergePref1 = "";
                this.GoodMergePref2 = "";
                this.GoodMergePref3 = "";
                this.MountImages = false;
                this.EscapeToExit = false;
            }
        }

        public bool IsDefault
        {
            get { return ID == -1; }
        }

        public int ID
        {
            get;
            set;
        }

        public string Title
        {
            get;
            set;
        }

        public int EmulatorID
        {
            get;
            set;
        }

        public string EmulatorPath
        {
            get;
            set;
        }

        public string WorkingDirectory
        {
            get;
            set;
        }

        public string Arguments
        {
            get;
            set;
        }

        public bool? UseQuotes
        {
            get;
            set;
        }

        public bool? SuspendMP
        {
            get;
            set;
        }

        public string GoodMergePref1
        {
            get;
            set;
        }

        public string GoodMergePref2
        {
            get;
            set;
        }

        public string GoodMergePref3
        {
            get;
            set;
        }

        public bool MountImages
        {
            get;
            set;
        }

        public bool EscapeToExit
        {
            get;
            set;
        }

        #region DBInterface Members

        public const string TABLE_NAME = "EmulatorProfiles";

        const string TABLE_STRING =
            "uid int," +
            "title varchar(200)," +
            "emulator_id int," +
            "emulator_path varchar(200)," +
            "working_path varchar(200)," +
            "usequotes char(5)," +
            "args varchar(200)," +
            "suspend_mp char(5)," +
            "goodmerge_pref1 varchar(10)," +
            "goodmerge_pref2 varchar(10)," +
            "goodmerge_pref3 varchar(10)," +
            "mountimages char(5)," +
            "escapetoexit char(5)," +
            "PRIMARY KEY(uid)";

        const string INSERT_STRING =
            "{0}, " + //id
            "'{1}', " + //encode(title)
            "{2}, " + //emuId
            "'{3}', " + //encode(emuPath)
            "'{4}', " + //encode(workingDir)
            "'{5}', " + //useQuotes
            "'{6}', " + //encode(args)
            "'{7}', " + //suspendMP
            "'{8}', " + //encode(goodPref1)
            "'{9}', " + //encode(goodPref2)
            "'{10}', " + //encode(goodPref3)
            "'{11}'," + //mountImages
            "'{12}'"; //escape to exit

        const string UPDATE_STRING =
            "title='{1}', " +
            "emulator_path='{3}', " +
            "working_path='{4}', " +
            "usequotes='{5}', " +
            "args='{6}', " +
            "suspend_mp='{7}', " +
            "goodmerge_pref1='{8}', " +
            "goodmerge_pref2='{9}', " +
            "goodmerge_pref3='{10}', " +
            "mountimages='{11}', " +
            "escapetoexit='{12}' " +
            "WHERE uid={0}";

        object[] DBParams
        {
            get
            {
                return new object[] 
                { 
                    ID,
                    DB.Encode(Title),
                    EmulatorID,
                    DB.Encode(EmulatorPath),
                    DB.Encode(WorkingDirectory),
                    UseQuotes,
                    DB.Encode(Arguments),
                    SuspendMP,
                    DB.Encode(GoodMergePref1),
                    DB.Encode(GoodMergePref2),
                    DB.Encode(GoodMergePref3),
                    MountImages,
                    EscapeToExit
                };
            }
        }

        public static EmulatorProfile CreateProfile(SQLite.NET.SQLiteResultSet.Row sqlRow)
        {
            if (sqlRow.fields.Count != 13)
            {
                Logger.LogError("Unable to create Profile, invalid database row");
                return null;
            }

            System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.InvariantCulture;

            EmulatorProfile profile = new EmulatorProfile(null, false);
            profile.ID = int.Parse(sqlRow.fields[0], culture);
            profile.Title = DB.Decode(sqlRow.fields[1]);
            profile.EmulatorID = int.Parse(sqlRow.fields[2], culture);
            profile.EmulatorPath = DB.Decode(sqlRow.fields[3]);
            profile.WorkingDirectory = DB.Decode(sqlRow.fields[4]);
            profile.UseQuotes = Boolean.Parse(sqlRow.fields[5]);
            profile.Arguments = DB.Decode(sqlRow.fields[6]);
            profile.SuspendMP = Boolean.Parse(sqlRow.fields[7]);
            profile.GoodMergePref1 = DB.Decode(sqlRow.fields[8]);
            profile.GoodMergePref2 = DB.Decode(sqlRow.fields[9]);
            profile.GoodMergePref3 = DB.Decode(sqlRow.fields[10]);
            profile.MountImages = Boolean.Parse(sqlRow.fields[11]);
            profile.EscapeToExit = Boolean.Parse(sqlRow.fields[12]);
            return profile;
        }

        public static string DBTableString
        {
            get
            {
                return "CREATE TABLE " + TABLE_NAME + "(" + TABLE_STRING + ")";
            }
        }

        public string GetDBInsertString()
        {
            return "INSERT INTO " + TABLE_NAME + " VALUES(" + string.Format(System.Globalization.CultureInfo.InvariantCulture, INSERT_STRING, DBParams) + ")";
        }

        public string GetDBUpdateString()
        {
            return "UPDATE " + TABLE_NAME + " SET " + string.Format(System.Globalization.CultureInfo.InvariantCulture, UPDATE_STRING, DBParams);
        }

        public void Save()
        {
            if (ID == -1)
            {
                saveDefault();
                return;
            }

            lock (DB.Instance.SyncRoot)
            {
                if (Exists())
                {
                    DB.Instance.ExecuteWithoutLock(GetDBUpdateString());
                }
                else
                {
                    SQLite.NET.SQLiteResultSet result = DB.Instance.ExecuteWithoutLock("SELECT MAX(uid)+1 FROM {0}", TABLE_NAME);
                    if (result.Rows.Count > 0)
                        ID = MediaPortal.Database.DatabaseUtility.GetAsInt(result, 0, 0);
                    else
                        ID = 0;

                    DB.Instance.ExecuteWithoutLock(GetDBInsertString());
                }
            }
        }

        void saveDefault()
        {
            Emulator emu = DB.Instance.GetEmulator(EmulatorID);
            if (emu == null)
                return;

            emu.PathToEmulator = EmulatorPath;
            emu.WorkingFolder = WorkingDirectory;
            emu.UseQuotes = UseQuotes == true;
            emu.Arguments = Arguments;
            emu.SuspendRendering = SuspendMP == true;
            emu.GoodmergePref1 = GoodMergePref1;
            emu.GoodmergePref2 = GoodMergePref2;
            emu.GoodmergePref3 = GoodMergePref3;
            emu.MountImages = MountImages;
            emu.EscapeToExit = EscapeToExit;

            emu.Save();
        }

        public void Delete()
        {
            if (ID < 0)
                return;

            DB.Instance.Execute("DELETE FROM {0} WHERE uid={1}", TABLE_NAME, ID);
        }

        public bool Exists()
        {
            return DB.Instance.Execute("SELECT 1 FROM {0} WHERE uid={1}", TABLE_NAME, ID).Rows.Count 
                != 0;
        }

        #endregion
    }
}
